﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace HFUTCourseSimulation.Widget {
    /// <summary>
    /// Interaction logic for ColorPicker.xaml
    /// </summary>
    public partial class ColorPicker : Window {
        public ColorPicker() {
            InitializeComponent();
        }

        public Kernel.Data.Ui.ColorPair CurrentColor { get; set; }
        private Color _foregroundBackup, _backgroundBackup;

        private void uiMainWindow_Loaded(object sender, RoutedEventArgs e) {
            // Build color list
            BuildColorList();
            // Set context
            uiPicker.DataContext = CurrentColor;
            // Backup color for restoring
            _foregroundBackup = CurrentColor.Foreground;
            _backgroundBackup = CurrentColor.Background;
        }

        private void uiMainWindow_Closed(object sender, EventArgs e) {
            uiPicker.DataContext = null;
        }

        #region Color Box Stuff

        private Border CreateColorBox(Util.ColorPair c, string name) {
            var colorBox = new Border();
            colorBox.Width = 100;
            colorBox.Height = 100;
            colorBox.Background = new SolidColorBrush(c.Background);
            colorBox.BorderBrush = new SolidColorBrush(Colors.Black);
            colorBox.BorderThickness = new Thickness(1);
            colorBox.CornerRadius = new CornerRadius(5);
            colorBox.Margin = new Thickness(5);
            colorBox.Cursor = Cursors.Hand;

            var colorText = new TextBlock();
            colorText.Text = name;
            colorText.Foreground = new SolidColorBrush(c.Foreground);
            colorText.HorizontalAlignment = HorizontalAlignment.Center;
            colorText.VerticalAlignment = VerticalAlignment.Center;
            colorBox.Child = colorText;

            return colorBox;
        }

        private class ColorPropertyWrapper {
            public ColorPropertyWrapper(PropertyInfo prop) {
                _prop = prop;
            }

            public string GetName() => _prop.Name;
            public Util.ColorPair GetColor() {
                var value = _prop.GetValue(null);
                if (value is Util.ColorPair color) {
                    return color;
                } else {
                    return new Util.ColorPair();
                }
            }

            private PropertyInfo _prop;
        }

        private IEnumerable<ColorPropertyWrapper> FilterColorProperties(Type t) {
            return t.GetProperties(BindingFlags.Public | BindingFlags.Static)
                .Where((prop) => prop.PropertyType == typeof(Util.ColorPair))
                .Select((prop) => new ColorPropertyWrapper(prop));
        }

        private Dictionary<object, Util.ColorPair> _knownColorPresets = new Dictionary<object, Util.ColorPair>();

        private void BuildColorList() {
            _knownColorPresets .Clear();

            uiMdColorPresetList.Children.Clear();
            foreach (var prop in FilterColorProperties(typeof(Util.ColorPreset.MdColors))) {
                var box = CreateColorBox(prop.GetColor(), prop.GetName());
                box.MouseDown += ColorBox_Click;
                uiMdColorPresetList.Children.Add(box);
                _knownColorPresets.Add(box, prop.GetColor());
            }
        }

        private void ColorBox_Click(object sender, MouseButtonEventArgs e) {
            if (_knownColorPresets.TryGetValue(sender, out var value)) {
                CurrentColor.Foreground = value.Foreground;
                CurrentColor.Background = value.Background;
            }
        }

        #endregion

        #region Ui Handlers

        private void uiForegroundPicker_MouseDown(object sender, MouseButtonEventArgs e) {
            var color = Util.Win32Dialog.PickColor();
            if (color is null) return;
            else CurrentColor.Foreground = color.Value;
        }
        private void uiBackgroundPicker_MouseDown(object sender, MouseButtonEventArgs e) {
            var color = Util.Win32Dialog.PickColor();
            if (color is null) return;
            else CurrentColor.Background = color.Value;
        }

        private void uiBtnOk_Click(object sender, RoutedEventArgs e) {
            this.Close();
        }

        private void uiBtnCancel_Click(object sender, RoutedEventArgs e) {
            // Restore and quit
            CurrentColor.Foreground = _foregroundBackup;
            CurrentColor.Background = _backgroundBackup;
            this.Close();
        }

        #endregion

    }
}
